#ifndef SOUP_H_INCLUDED
#define SOUP_H_INCLUDED

#include "Facet.h"
#include "BaseMaterial.h"
#include "Vertex.h"
#include "ObjGroup.h"

/**
@file
@author F. Aubert
@brief Opération sur les soupes de polygones
TODO : !!! delete sur vf, ...
*/

namespace prog3d {
/**
@class Soup
@brief Représentation des polyèdres par un ensemble de sommets et ensemble de facettes
*/

class Soup {

  BaseMaterial *_baseMaterial;

	/// ensemble des facettes
  AFacet vf;
	/// ensemble des sommets
  AVertex vv;
	/// ensemble des normales aux sommets
  AVector3 vn;

  /// ensemble des coordonnées de texture
  AVector3 vt;


  ObjGroup *_currentGroup;
  Array<ObjGroup> _group;

  unsigned int drawMode;

public:

  void eraseFacet(int i);
  void eraseFacet(Facet *f);
  void eraseFacet(AFacet::iterator i);


  Soup();
  void setDrawMode(unsigned int mode);
  void draw();
  void dilate(float k);
  void drawNormal();
  double minBox(int coord);
  double maxBox(int coord);

  void setNumber();

  void adaptBox(float x1,float x2, float y1, float y2, float z1, float z2);

  Vertex *getVertex(int i);
  Vector3 *getNormal(int i);

	Vertex *createVertex();
	Vertex *createVertex(const Vector3 &p);
	virtual Facet *createFacet();

  const AFacet &getAllFacet() const;
  const AVertex &getAllVertex() const;

  Facet *getFacet(unsigned int i);

  unsigned int nbFacet();
  unsigned int nbFace();
  unsigned int nbVertex();
  const Vector3 &point(unsigned int i);
  const Vector3 &normal(unsigned int i);
  Facet *face(unsigned int i);
  Vertex *vertex(unsigned int i);


  void addFacet(Facet* f);
  void addVertex(Vertex *v);
  void addNormal(Vector3 *n);

  Vector3 *createTexCoord(const Vector3 &t);
  Vector3 *getTexCoord(unsigned int i);

	void print(const std::string &mesg);

  void translate(float x,float y,float z);
  void scale(float k);
  void scale(double kx,double ky,double kz);

  void writeOBJ(std::string nom);
  void readOBJ(std::string nom);

  void computeVertexNormal();
  void computeFaceNormal();
  void opposeNormal();

  /// triangule les facettes.
  void triangulate();

  void shareMaterial(BaseMaterial *m);
  void addGroup(ObjGroup *o);
  void setCurrentGroup(ObjGroup *o);
  BaseMaterial *baseMaterial();

  ObjGroup *findGroup(std::string s);

  void enableGroup(const std::string &nom);
  void disableGroup(const std::string &nom);
  void enableAllGroup();
  void disableAllGroup();
  void printGroup();

  void buildEdge();
  void eraseDuplicateVertex();

  ~Soup();
};


}

#endif // SOUP_H_INCLUDED
